const _ = require('lodash');
const async = require('async');
const LoopBackContext = require('loopback-context');
const services = require('../../services');
const enums = require('../../enums');

const commonService = services.common;
const eLancoService = services.eLanco;

module.exports = (req, res, callback) => {
  const context = LoopBackContext.getCurrentContext();
  const form = context.get('form');
  const flow = context.get('flow');
  const formDetail = context.get('formDetail');
  const formId = req.body.formId;
  const id = req.params.id;
  const formDetailData = req.body.formDetail;
  const employeeId = commonService.getEmployeeId();
  const models = commonService.getModels();
  const { WfRunInstance: formDetailModel, WfRunFlowDetail: approvalDetailModel } = models;
  let approvalFinalStep = formDetail.approvalFinalStep;
  let skipStep = 0;
  const getApprovalDetail = (next) => {
    commonService.getDetail(approvalDetailModel, {
      where: {
        formId,
        instanceId: id,
        approvalStep: formDetail.approvalStep,
        approvalStatus: enums.approvalStatus.pending,
        approverEmployeeId: employeeId,
      },
    }, next);
  };
  const saveApprovalDetail = (approvalDetail, next) => {
    if (!approvalDetail) return callback(commonService.getError(enums.errorCode.forbidden));
    approvalDetailModel.upsert({
      id: approvalDetail.id,
      approvalStatus: enums.approvalStatus.approval,
      comment: formDetailData.comment,
      approvalDate: new Date(),
    }, next);
  };
  const getApprovalList = (approvalDetail, next) => {
    if (!flow.flowRun.isDynamicFlow) return next(null, null);
    eLancoService.getDynamicFlowApprovalList(form, formDetail, formDetail.approvalStep + 1, (error, DynamicFlowApprovalFinalStep, approvalList, nextStepIndex) => {
      skipStep = nextStepIndex - formDetail.approvalStep;
      approvalFinalStep = DynamicFlowApprovalFinalStep;
      next(error, approvalList);
    });
  };
  const createApprovalList = (approvalList, next) => {
    if (!flow.flowRun.isDynamicFlow) return next(null, null);
    approvalDetailModel.create(approvalList, next);
  };
  const saveFormDetail = (data, next) => {
    let approvalStep = _.toNumber(formDetail.approvalStep);
    let formStatus = _.toNumber(formDetail.formStatus);
    if (approvalStep == approvalFinalStep) {
      formStatus = enums.formStatus.completed;
    } else {
      formStatus += skipStep + 1;
      approvalStep += skipStep + 1;
    }
    formDetailModel.upsert({
      id,
      formId,
      approvalStep,
      approvalFinalStep,
      formStatus,
      formDetail: formDetailData,
    }, next);
  };
  const getFormDetail = (data, next) => {
    eLancoService.getFormDetailIncludeAll(formId, id, (error, formDetail) => {
      context.set('formDetail', formDetail);
      context.set('approvalList', formDetail.approvalList());
      next(error, formDetail);
    });
  };
  let taskList = [getApprovalDetail, saveApprovalDetail];
  if (flow.flowRun.isDynamicFlow) taskList = taskList.concat([getApprovalList, createApprovalList]);
  taskList = taskList.concat([saveFormDetail, getFormDetail]);
  async.waterfall(taskList, callback);
};
